#ifndef _BODY_
#define _BODY_

#include <ostream>

#define GRAVCONST (6.673e-11)

struct Particle;

class Vector{
	private:
		double mX;
		double mY;
		double mZ;
	public:
		Vector();
		Vector(double x, double y, double z);
		Vector(Particle& part);

		void clear();	

		inline double& x(){return this->mX;}
		inline double& y(){return this->mY;}
		inline double& z(){return this->mZ;}
};

struct Particle
{
	unsigned int id;
	double mass;
	double posx;
	double posy;
	double posz;
	double dummy;
};

class Body
{
	private:
		Particle part; //contains position & mass & id of the object
		double mDt;    //time variable 
		Vector accelertion; //contains accelertion x,y,z
	public:
		Body();
		~Body();
		
		void init(unsigned int id,double dt);
		void updatePosition();
		void calcAcceleration(Particle* particle, int amount);
		void calcAcceleration(Body* body, int amount);
		void setMass(double mass);
		void setDt(double dt);
		void setPos(double x, double y, double z);
	
		//getter-util
		inline unsigned int getId(){return this->part.id;}
		inline Particle getParticle(){return this->part;}
		inline double getMass(){return this->part.mass;}

		//getter-position
		inline double getPosX(){return this->part.posx;}
		inline double getPosY(){return this->part.posy;}
		inline double getPosZ(){return this->part.posz;}
		
		//getter-accelertion		
		inline double getVelX(){
			return ((-1)*GRAVCONST * this->accelertion.x() * mDt);
		}
		inline double getVelY(){
			return ((-1)*GRAVCONST * this->accelertion.y() * mDt);
		}
		inline double getVelZ(){
			return ((-1)*GRAVCONST * this->accelertion.z() * mDt);
		}
		inline Vector getAcceleration(){return this->accelertion;}

		friend std::ostream& operator<<(std::ostream& str, Body& body);				

};

#endif

